package vip.fuxk.blog.common;

import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import org.smartboot.http.server.impl.HttpRequestImpl;

import java.io.PrintWriter;
import java.io.StringWriter;

@Slf4j
@Component //index 为顺序位（不加，则默认为0）
public class AppFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        //1.开始计时（用于计算响应时长）
        long start = System.currentTimeMillis();
        Object req = ctx.request();
        String path = ctx.pathNew();
        boolean jsonContent = false;
        if(req instanceof HttpRequestImpl){
            HttpRequestImpl  request = (HttpRequestImpl) req;
            String accept =  request.getHeader("Accept");
            if(null!=accept && accept.contains("json")){
                jsonContent =true;
            }
        }

        try {

            //2.记录请求数据日志
//            log.info("Request data: {}", ctx); //getRequestData 需要自己写，把 ctx 里的请求数据转为 string

            //3.执行处理
            chain.doFilter(ctx);

            if ( !ctx.getHandled() || ctx.status() == 404) {
                log.error("404error,path:{}",path);
                ctx.redirect("/404");
            }
            
            //4.记录响应数据日志
//            log.info("Response data: {}", ctx.result); //getResponseData 需要自己写，把 ctx 里的请求数据转为 string
        } catch (Throwable e) {
            e.printStackTrace();
            //4.异常捕捉与控制（并标为500错误）
            String errorMsg = "遇到错误啦：（";
            if(
               e.getClass().getName().startsWith("com.baomidou.mybatisplus") ||
               e.getClass().getName().startsWith("org.apache.ibatis")
            ){
                errorMsg =  "操作数据时，遇到异常：（" ;
                ctx.status(200);
            } else if(e.getClass().getName().startsWith("freemarker")){
                errorMsg =  "页面异常：（" ;
                ctx.status(200);
            }else{
                ctx.status(500);
            }
            if(jsonContent){
                ctx.output(R.error(errorMsg).toString());
            }else{

                StringWriter errors = new StringWriter();

                e.printStackTrace(new PrintWriter(errors));

                StringBuilder sb = new StringBuilder();
                sb.append("<h1>");
                sb.append(errorMsg);
                sb.append("</h1>");

                sb.append("<template errorMsg >");
                sb.append(e.getMessage());
                sb.append("</template>");

                sb.append("<template stackTrace >");
                sb.append(errors);
                sb.append("</template>");
                ctx.outputAsHtml(sb.toString());
            }
        }

        //5.获得接口响应时长
        long times = System.currentTimeMillis() - start;
        if(times>1000){
            log.warn("用时：{} ==> url:{}",times,path);
        }else{
//            log.info("用时：{} ==> url:{}",times,path);
        }
    }
}  